package com.jhgsys.internal.common.controller;

import com.jhgsys.internal.common.entity.FebsResponse;
import com.jhgsys.internal.common.utils.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * UEditor文件上传辅助类
 *
 */
public class FileUploader {
	public static String MSG_ERROR_FILE_TYPE = "文件类型不正确！";
	public static String MSG_ERROR_NO_FILE = "未包含上传文件！";
	// 输出文件地址
	private String url = "";
	// 上传文件名
	private String fileName = "";
	// 状态
	private String state = "";
	// 文件类型
	private String type = "";
	// 原始文件名
	private String originalName = "";
	// 文件大小
	private long size = 0;

	private HttpServletRequest request = null;
	private final String title = "";

	// 保存路径
	private String savePath = "upload";
	// 文件允许格式
	private String[] allowFiles = { ".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", ".gif", ".png",
			".jpg", ".jpeg", ".bmp" };
	// 文件大小限制，单位KB
	private int maxSize = 10000;

	private final HashMap<String, String> errorInfo = new HashMap<String, String>();

	public FileUploader(HttpServletRequest request) {
		this.request = request;
		HashMap<String, String> tmp = this.errorInfo;
		tmp.put("SUCCESS", "SUCCESS"); // 默认成功
		tmp.put("NOFILE", "未包含文件上传域");
		tmp.put("TYPE", "不允许的文件格式");
		tmp.put("SIZE", "文件大小超出限制");
		tmp.put("ENTYPE", "请求类型ENTYPE错误");
		tmp.put("REQUEST", "上传请求异常");
		tmp.put("IO", "IO异常");
		tmp.put("DIR", "目录创建失败");
		tmp.put("UNKNOWN", "未知错误");

	}

	public void upload() throws Exception {

		MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
		Iterator<String> fns = mRequest.getFileNames();
		try {

			while (fns.hasNext()) {
				String s = fns.next();
				System.out.println(s + "===" + mRequest.getFile(s));
				MultipartFile mFile = mRequest.getFile(s);
				if (mFile.getSize() > this.maxSize * 1024L) {
					this.state = this.errorInfo.get("SIZE");
				} else if (mFile.isEmpty()) {
					this.state = this.errorInfo.get("NOFILE");
				} else {

					this.originalName = mFile.getOriginalFilename();
					if (!this.checkFileType(this.originalName)) {
						this.state = this.errorInfo.get("TYPE");
						continue;
					}
					this.fileName = this.getName(this.originalName);
					this.type = this.getFileExt(this.fileName);
					this.url = this.savePath + "/" + this.fileName;
					File file = new File(this.getPhysicalPath(this.url));
					// 存储文件
					FileUtils.copyInputStreamToFile(mFile.getInputStream(), file);

					// 裁剪文件
					String basePath = UploadPathUtil.getRootPath();

					ImageUtils.zoomImage(basePath + this.savePath + "/" + this.fileName,
							basePath + this.savePath + "/small/" + this.fileName, 200, 0);

					this.state = this.errorInfo.get("SUCCESS");
					this.size = file.length();
					// UE中只会处理单张上传，完成后即退出
					break;

				}
			}
		} catch (Exception e) {
			this.state = this.errorInfo.get("UNKNOWN");
		}
	}

	/**
	 * 文件类型判断
	 *
	 * @param fileName
	 * @return
	 */
	private boolean checkFileType(String fileName) {
		Iterator<String> type = Arrays.asList(this.allowFiles).iterator();
		while (type.hasNext()) {
			String ext = type.next();
			if (fileName.toLowerCase().endsWith(ext)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取文件扩展名
	 *
	 * @return string
	 */
	private String getFileExt(String fileName) {
		return fileName.substring(fileName.lastIndexOf("."));
	}

	/**
	 * 依据原始文件名生成新文件名
	 *
	 * @return
	 */
	private String getName(String fileName) {

		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");

		// 生成文件名
		String fullImgName = sdf.format(date) + new Random().nextInt(10000) + this.getFileExt(fileName);

		return fullImgName;
	}

	/**
	 * 根据字符串创建本地目录 并按照日期建立子目录返回
	 *
	 * @param path
	 * @return
	 */
	@SuppressWarnings("unused")
	private String getFolder(String path) {
		// SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
		// path += "/" + formater.format(new Date());
		File dir = new File(this.getPhysicalPath(path));
		if (!dir.exists()) {
			try {
				dir.mkdirs();
			} catch (Exception e) {
				this.state = this.errorInfo.get("DIR");
				return "";
			}
		}
		return path;
	}

	/**
	 * 根据传入的虚拟路径获取物理路径
	 *
	 * @param path
	 * @return
	 */
	private String getPhysicalPath(String path) {

		return new File(UploadPathUtil.getRootPath()) + "/" + path;

	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public void setAllowFiles(String[] allowFiles) {
		this.allowFiles = allowFiles;
	}

	public void setMaxSize(int size) {
		this.maxSize = size;
	}

	public long getSize() {
		return this.size;
	}

	public String getUrl() {
		return this.url;
	}

	public String getFileName() {
		return this.fileName;
	}

	public String getState() {
		return this.state;
	}

	public String getTitle() {
		return this.title;
	}

	public String getType() {
		return this.type;
	}

	public String getOriginalName() {
		return this.originalName;
	}

	public static FebsResponse fileUpCommon(HttpServletRequest request, HttpServletResponse response, String path) {
		return  fileUpCommon(request, response, path, 0);
	}
	public static FebsResponse fileUpCommon(HttpServletRequest request, HttpServletResponse response, String path,Integer width) {
		// 允许上传的文件格式的列表
		response.setContentType("text/html");
		// 设置字符编码为UTF-8, 这样支持汉字显示
		response.setCharacterEncoding("UTF-8");
		MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
		Iterator<String> fns = mRequest.getFileNames();
		List<Map> fileList = new ArrayList<>();
		if (!fns.hasNext()) {
			return new FebsResponse().fail().message(MSG_ERROR_NO_FILE);
		}
		while (fns.hasNext()) {
			String s = fns.next();
			System.out.println(s + "===" + mRequest.getFile(s));
			MultipartFile mFile = mRequest.getFile(s);
			if (mFile.isEmpty()) {
				return new FebsResponse().fail().message(MSG_ERROR_NO_FILE);
			} else {

				String originFileName = mFile.getOriginalFilename();
				// 获取后缀名
				String suffix = originFileName.split("\\.")[originFileName.split("\\.").length - 1];

				String basePath = UploadPathUtil.getRootFilesPath() + path;
				// 获取文件文件夹路径
				if ("png".equalsIgnoreCase(suffix) || "jpg".equalsIgnoreCase(suffix)
						|| "jpeg".equalsIgnoreCase(suffix) || "gif".equalsIgnoreCase(suffix)) {
					basePath = UploadPathUtil.getRootImagesPath() + path;
				}

				File dir = new File(basePath);
				// 判断文件夹是否存在
				if (!dir.exists()) {
					dir.mkdirs();
				}

				// 获取类型
				String type = mFile.getContentType();

				if (!type.contains("image") && !type.contains("document") && !type.contains("msword")
						&& !type.contains("sheet") && !type.contains("excel") && !type.contains("presentation")
						&& !type.contains("powerpoint") && !type.contains("pdf") && !type.contains("text") && !suffix.contains("zip") && !suffix.contains("rar")) {
					return new FebsResponse().fail().message(MSG_ERROR_FILE_TYPE);
				}

				// 生成文件名
				String fullImgName = FebsUtil.uuid() + "." + suffix;

				// 上传后的文件名
				File file = new File(basePath, fullImgName);
				try {
					// 存储文件
					FileUtils.copyInputStreamToFile(mFile.getInputStream(), file);

					if (type.contains("image")) {
						int widthBig = 1000;
						int widthSmall = 200;
						if (width != null && width > 0) {
							widthBig = width;
							widthSmall = width;
						}

						// 裁剪文件
						ImageUtils.zoomImage(basePath + "/" + fullImgName, basePath + "/" + fullImgName, widthBig, 0);
						// 裁剪文件
						ImageUtils.zoomImage(basePath + "/" + fullImgName, basePath + "/small/" + fullImgName, widthSmall, 0);
					}

					// 返回文件名
					Map<String, Object> filedto = new HashMap<>();
					filedto.put("fileName", originFileName);
					filedto.put("fileType", suffix);
					filedto.put("filePath", fullImgName);
					fileList.add(filedto);

				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return new FebsResponse().success().data(fileList);// 返回结果
	}

	public static FebsResponse fileUpCommon1(HttpServletRequest request, HttpServletResponse response, String path,String flg) {

		// 允许上传的文件格式的列表
		response.setContentType("text/html");
		// 设置字符编码为UTF-8, 这样支持汉字显示
		response.setCharacterEncoding("UTF-8");
		MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
		Iterator<String> fns = mRequest.getFileNames();
		List<Map> fileList = new ArrayList<>();
		if (!fns.hasNext()) {
			return new FebsResponse().fail().message(MSG_ERROR_NO_FILE);
		}
		while (fns.hasNext()) {
			String s = fns.next();
			System.out.println(s + "===" + mRequest.getFile(s));
			MultipartFile mFile = mRequest.getFile(s);
			if (mFile.isEmpty()) {
				return new FebsResponse().fail().message(MSG_ERROR_NO_FILE);
			} else {
				// 获取文件文件夹路径
				String basePath = UploadPathUtil.getRootPath() + path;
				File dir = new File(basePath);
				// 判断文件夹是否存在
				if (!dir.exists()) {
					dir.mkdirs();
				}

				// 获取类型
				String type = mFile.getContentType();

				if (!type.contains("image") && !type.contains("document") && !type.contains("msword")
						&& !type.contains("sheet") && !type.contains("excel") && !type.contains("presentation")
						&& !type.contains("powerpoint") && !type.contains("pdf") && !type.contains("text")) {
					return new FebsResponse().fail().message(MSG_ERROR_FILE_TYPE);
				}

				String originFileName = mFile.getOriginalFilename();
				// 获取后缀名
				String suffix = originFileName.split("\\.")[originFileName.split("\\.").length - 1];

				// 生成文件名
				String fullImgName = FebsUtil.uuid() + "." + suffix;

				// 上传后的文件名
				File file = new File(basePath, fullImgName);
				try {
					// 存储文件
					FileUtils.copyInputStreamToFile(mFile.getInputStream(), file);
					if (type.contains("image")) {
						// 裁剪文件
						ImageUtils.zoomImage(basePath + "/" + fullImgName, basePath + "/" + fullImgName, 1000, 0);
						// 裁剪文件
						ImageUtils.zoomImage(basePath + "/" + fullImgName, basePath + "/" + fullImgName, 200, 0);
					}

					// 返回文件名
					Map<String, Object> filedto = new HashMap<>();
					filedto.put("fileName", originFileName);
					filedto.put("fileType", suffix);
					filedto.put("filePath", fullImgName);
					fileList.add(filedto);

				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return new FebsResponse().success().data(fileList);// 返回结果
	}

	public static FebsResponse fileUpCommon(Plupload plupload, HttpServletRequest request, String path) {
		plupload.setRequest(request);
		try {
			String videoPath = path + "/" + DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd");
			File dir = new File(UploadPathUtil.getRootPath() + videoPath);
			//上传文件
			PluploadUtil.upload(plupload, dir);
			//判断文件是否上传成功（被分成块的文件是否全部上传完成）
			if (PluploadUtil.isUploadFinish(plupload)) {
				//File uploadFile = new File(dir.getPath(), plupload.getFileName());
				//String imageName = plupload.getFileName().substring(plupload.getFileName().lastIndexOf(".") + 1) + ".jpg";
				//Video2ImageUtil.randomGrabberFFmpegImage(uploadFile.getPath(), dir.getPath(), imageName);
				Map<String, Object> data = new HashMap<>();
				data.put("fileName", plupload.getName());
				data.put("filePath", "files/" + videoPath + "/" + plupload.getFileName());
				data.put("smallPath", "files/" + videoPath + "/" + plupload.getSmallFileName());
				data.put("message", plupload.getChunk() + "," + plupload.getName() + "," + plupload.getChunks());
				return new FebsResponse().success().data(data);
			} else {
				return new FebsResponse().success().message(plupload.getChunk() + "," + plupload.getName() + "," + plupload.getChunks());
			}
		} catch (Exception e) {
			return new FebsResponse().fail().message("文件上传失败！Error：" + e.getMessage());
		}
	}

	public  static boolean checkFileType(String fileName, String[] allowFiles) {
		Iterator<String> type = Arrays.asList(allowFiles).iterator();
		while (type.hasNext()) {
			String ext = type.next();
			if (fileName.toLowerCase().endsWith(ext)) {
				return true;
			}
		}
		return false;
	}

	// 文件允许格式
	public  static String[] allowOtherFiles = { ".rar", ".zip", ".pdf", ".txt", ".ppt", ".pptx", ".doc", ".docx", ".xls",
										 ".xlsx",".rp" };
	public static String[] allowImageFiles = { ".gif", ".png", ".jpg", ".jpeg", ".bmp" };
	public static String[] allowVideoFiles = { ".swf", ".wmv", ".mpg", ".m4v", ".mp4", ".flv", ".3gp", ".avi", ".rmvb",
										 ".mkv"};



}
